/*
 *  CRS.h
 *  NSE_SOLVER
 *
 *  Created by Patrick Zulian on 3/2/11.
 *  Copyright 2011 ICS - USI - Lugano. All rights reserved.
 *
 */

#ifndef NSE_SOLVER_CRS_H
#define NSE_SOLVER_CRS_H

#include "Array.h"
#include "MatrixUtils.h"
/**
 * \brief The CRS class ... TODO Doc
 * \tparam T 
 */ 


namespace nsesolver {
	
	template< typename Storage = Array< int > >
	class CRS {
	private:
		Storage rowCount;
		Storage columnIndex;
		
	public:
		template< class MatrixType >
		inline
		static const CRS CreateFrom(const MatrixType &m)
		{
			return CreateFrom(m, NonZeros(m));
		}
		
		
		
		template< class MatrixType >
		inline static const CRS CreateFrom(const MatrixType &m, const int nnz)
		{
			Storage rowCount(m.rows());
			Storage columnIndex(nnz);
			
			rowCount.allSet(0);
			int nnzCount = 0;
			for (int i = 0; i < m.rows(); i++) {
				for (int j = 0; j < m.columns(); j++) {
					if (m(i, j) != 0) {
						rowCount[i]++;
						columnIndex[nnzCount++] = j;
					}
				}
			}
			
			return CRS(rowCount, columnIndex);
		}
		
		
		CRS(const Storage & rowCount, const Storage &columnIndex)
		: rowCount(rowCount), columnIndex(columnIndex)
		{}
		
		/**
		 *	The copy constructor
		 *	\param other the object from which the data is copied from. All fields are to be copied
		 *	
		 */
		CRS(const CRS &other)
		: rowCount(other.rowCount), columnIndex(other.columnIndex)
		{
			//TODO
		}
		
		inline
		const int getRowCount(const int i) const
		{
			return rowCount[i];
		}
		
		inline
		const int getColumnIndex(const int j) const
		{
			return columnIndex[j];
		}
		
		inline int nonZeros() const
		{
			return columnIndex.size();
		}
		
		/**
		 *	The copy operator
		 *	\param other the object from which the data is copied from. All fields are to be copied
		 *	
		 */
		CRS & operator=(const CRS &other)
		{
			if (this == &other) {
				return *this;
			}
			
			rowCount = other.rowCount;
			columnIndex = other.columnIndex;
			
			return *this;
		}
		
		/**
		 * The Destructor
		 */
		~CRS()
		{
			//TODO
		}
		
	};
	
}
#endif

